package com.didispace.service;

import com.didispace.web.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

@Service
public class HelloService {

    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    RestTemplate restTemplate;

    // p75 RestTemplate 详解
    public String restTemplateService() {
        StringBuilder result = new StringBuilder();

        // GET 请求  第一种：getForEntity 函数。 p75
        // getForEntity(String url, Class<T> responseType, Object... urlVariables)
        String titleOfGet1 = "GET 请求 第一种：getForEntity 函数。";
        result.append(titleOfGet1).append("<br>");
        // RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER-SERVICE/user1?name={1}", String.class, "didi");
        String body = responseEntity.getBody();
        result.append(body).append("<br>");

        result.append("而返回的 ResponseEntity对象中的 body 内容类型会根据第二个参数转换为 String 类型<br/>");
        result.append("返回的 body 是一个 User 对象类型<br/>");
        // This application has no explicit mapping for /error, so you are seeing this as a fallback.
        // RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<User> responseEntity2 = restTemplate.getForEntity("http://USER-SERVICE/user4?name={1}", User.class, "didi");
        User body2 = responseEntity2.getBody();
        result.append(body2.toString()).append("<br>");
        ResponseEntity<User> responseEntity3 = restTemplate.getForEntity("http://USER-SERVICE/user2?name={1}&age={2}", User.class, "didi", 17);
        User body3 = responseEntity3.getBody();
        result.append(body3.toString()).append("<br>");

        // p76
        result.append("2. 使用 Map 类型<br/>");
        // getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables)
        // RestTemplate restTemplate = new RestTemplate();
        Map<String, String> params = new HashMap<>();
        params.put("name", "dada");
        ResponseEntity<String> responseEntity4 = restTemplate.getForEntity("http://USER-SERVICE/user1?name={name}", String.class, params);
        String body4 = responseEntity4.getBody();
        result.append(body4).append("<br>");

        // p76
        // getForEntity(URI url, Class<T> responseType)
        // RestTemplate restTemplate = new RestTemplate();
        result.append("3. 使用 getForEntity(URI url, Class<T> responseType)<br/>");
        UriComponents uriComponents = UriComponentsBuilder.fromUriString(
                "http://USER-SERVICE/user1?name={name}")
                .build()
                .expand("dodo")
                .encode();
        URI uri = uriComponents.toUri();
        // ERROR：ResponseEntity<String> responseEntity5 = restTemplate.getForEntity(uri, String.class).getBody();
        String body5 = restTemplate.getForEntity(uri, String.class).getBody();
        result.append(body5).append("<br>");

        // GET 请求  第二种：getForObject 函数。 p77
        String titleOfGet2 = "GET 请求 第二种：getForObject 函数。";
        result.append(titleOfGet2).append("<br>");
        // RestTemplate restTemplate = new RestTemplate();
        String result1 = restTemplate.getForObject(uri, String.class);
        // result.append(result1).append("<br>");
        // RestTemplate restTemplate = new RestTemplate();
        // User result2 = restTemplate.getForObject(uri, User.class);
        // result.append(result2.getName()).append("<br>");
        result.append("p77 运行失败<br/>");

        String titleOfPost1 = "POST 请求 第一种：postForEntity 函数。";
        result.append(titleOfPost1).append("<br>");
        // POST 请求 第一种：postForEntity 函数。 p77
        // RestTemplate restTemplate = new RestTemplate();
        User user = new User("didi", 30);
        ResponseEntity<String> responseEntity6 =
                restTemplate.postForEntity("http://USER-SERVICE/user3", user, String.class);
        String body6 = responseEntity6.getBody();
        result.append(body6).append("<br>");

        String titleOfPost2 = "POST 请求 第二种：postForObject 函数。";
        result.append(titleOfPost2).append("<br>");
        // POST 请求 第二种：postForObject 函数。 p78
        // RestTemplate restTemplate = new RestTemplate();
        User user2 = new User("didi", 20);
        String postResult = restTemplate.postForObject("http://USER-SERVICE/user3", user2, String.class);
        result.append(postResult).append("<br>");

        String titleOfPost3 = "POST 请求 第三种：postForLocation 函数。";
        result.append(titleOfPost3).append("<br>");
        // POST 请求 第三种：postForLocation 函数。 p78
        User user3 = new User("didi", 40);
        URI responseURI = restTemplate.postForLocation("http://USER-SERVICE/user3", user3);
        result.append(responseURI).append("<br>");

        String titleOfPut = "PUT 请求。";
        result.append(titleOfPut).append("<br>");
        // // RestTemplate restTemplate = new RestTemplate();
        // Long id = 10001L;
        // User user4 = new User("didi", 40);
        // restTemplate.put("http://USER-SERVICE/user4/{1}", user4, id);
        //
        String titleOfDelete = "DELETE 请求。";
        result.append(titleOfDelete).append("<br>");
        // // RestTemplate restTemplate = new RestTemplate();
        // Long id2 = 10001L;
        // restTemplate.delete("http://USER-SERVICE//{1}", id2);

        return result.toString();
    }

    // p133  在 helloService 函数上增加@HystrixCornrnand 注解来指定回调方法
    @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService() {
        StringBuilder result = new StringBuilder();
        result.append(restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody()).append("<br>");
        return result.toString();
    }

    public String helloFallback() {
        return "error";
    }

    // restTemplate会用一个工具类去解析前面的url，提取出host，port等信息，如果不加参数，他就认为你不需要传参，所以map就不生效了。
    public String user2(String name) {
        final String uri = "http://localhost:9000/getUser1";
        Map<String, String> params = new HashMap<String, String>();
        params.put("name", "Garbo");
        params.put("age", "26");
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.getForObject(uri+ "/{name}", String.class, params);
        return result;
    }

    public User user3(String name) {
        final String uri = "http://localhost:9000/getUser1";
        Map<String, String> params = new HashMap<String, String>();
        params.put("name", "Garbo");
        params.put("age", "26");
        RestTemplate restTemplate = new RestTemplate();
        User result = restTemplate.getForObject(uri+ "/{name}", User.class, params);
        return result;
    }
}

